/***********************************************************************
 * Module:  User.java
 * Author:  Voja
 * Purpose: Defines the Class User
 ***********************************************************************/

package model.entity;

import static javax.persistence.CascadeType.ALL;
import static javax.persistence.FetchType.LAZY;
import static javax.persistence.GenerationType.IDENTITY;

import java.io.Serializable;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

@Entity
@Table(name = "user")
@NamedQuery(name = "findMailPassword", 
	query = "SELECT u FROM User u WHERE u.email like :mail AND u.password LIKE :password")
public class User implements Serializable{

	private static final long serialVersionUID = 1960834083626626615L;

	@Id
	@GeneratedValue(strategy = IDENTITY)
	@Column(name = "user_id", unique = true, nullable = false)
    private Integer id;
	
	@Column(name = "user_emailaddress", unique = false, nullable = true)
	private String email;
	
	@Column(name = "user_password", unique = false, nullable = true)
	private String password;
	
	@Column(name = "user_firstname", unique = false, nullable = true)
	private String firstName;
	
	@Column(name = "user_lastname", unique = false, nullable = true)
	private String lastName;
	
	@Column(name = "user_gender", unique = false, nullable = true)
	private Integer gender;
	
	@Temporal(TemporalType.DATE)
	@Column(name = "user_dateofbirth", unique = false, nullable = true)
	private Date dateOfBirth;
	
	@Column(name = "user_emailnotifications", unique = false, nullable = true)
	private Boolean emailNotifications;
   
	@ManyToMany(fetch=FetchType.EAGER)
	@JoinTable(
		name="follows",
	    joinColumns={@JoinColumn(name="following_id", referencedColumnName="user_id")},
	    inverseJoinColumns={@JoinColumn(name="follower_id", referencedColumnName="user_id")})
	private Set<User> followers=new HashSet<User>();
	
	@ManyToMany(fetch=FetchType.EAGER,mappedBy = "followers")
	private Set<User> following = new HashSet<User>();
	
	@OneToOne(fetch=FetchType.EAGER,optional = true)
	@JoinColumn(name = "favorite_album_id", referencedColumnName = "album_id", unique = true, nullable = true)
	private Album favorite;
	
	@OneToMany(cascade = { ALL }, fetch = FetchType.EAGER, mappedBy = "user")
	private Set<Album> albums=new HashSet<Album>();
	
	@OneToMany(cascade = { ALL }, fetch = FetchType.EAGER, mappedBy = "user")
	private Set<Rating> ratings=new HashSet<Rating>();
	
	@OneToMany(cascade = { ALL }, fetch = FetchType.EAGER, mappedBy = "user")
	private Set<Comment> comments=new HashSet<Comment>();
	
	@OneToOne(fetch=FetchType.EAGER, optional = true)
	@JoinColumn(name = "profile_id", referencedColumnName = "profile_id", nullable = true)
	private ProfileImage profileImage;

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public Integer getGender() {
		return gender;
	}

	public void setGender(Integer gender) {
		this.gender = gender;
	}

	public Date getDateOfBirth() {
		return dateOfBirth;
	}

	public void setDateOfBirth(Date dateOfBirth) {
		this.dateOfBirth = dateOfBirth;
	}

	public Boolean getEmailNotifications() {
		return emailNotifications;
	}

	public void setEmailNotifications(Boolean emailNotifications) {
		this.emailNotifications = emailNotifications;
	}

	public Set<User> getFollowers() {
		return followers;
	}

	public void setFollowers(Set<User> followers) {
		this.followers = followers;
	}

	public Set<User> getFollowing() {
		return following;
	}

	public void setFollowing(Set<User> following) {
		this.following = following;
	}

	public Album getFavorite() {
		return favorite;
	}

	public void setFavorite(Album favorite) {
		this.favorite = favorite;
	}

	public Set<Album> getAlbums() {
		return albums;
	}

	public void setAlbums(Set<Album> albums) {
		this.albums = albums;
	}

	public Set<Rating> getRatings() {
		return ratings;
	}

	public void setRatings(Set<Rating> ratings) {
		this.ratings = ratings;
	}

	public Set<Comment> getComments() {
		return comments;
	}

	public void setComments(Set<Comment> comments) {
		this.comments = comments;
	}

	public ProfileImage getProfileImage() {
		return profileImage;
	}

	public void setProfileImage(ProfileImage profileImage) {
		this.profileImage = profileImage;
	}

	public static long getSerialversionuid() {
		return serialVersionUID;
	}

	@Override
	public String toString() {
		return "User [id=" + id +"]";
	}
	
	@Override
	public boolean equals(Object obj) {
		if(!(obj instanceof User))
			return false;
		return ((User)obj).getId().intValue()==getId().intValue();
	}
	
	
}